package creation.singleton;

//1.饿汉式:静态常量 特点：类装载创建，可能会浪费内存
class  SingletonHungry {
    //1.私有化构造
    private SingletonHungry(){}
    //2.类内部创建对象
    private final static SingletonHungry instance = new SingletonHungry();
    //3.对外提供获取实例方法
    public static SingletonHungry getInstance() {
        return instance;
    }
}
//2.懒汉式线程不安全，
class SingletonLazy {
    //1.私有化构造
    private SingletonLazy(){}
    //2.类内部创建对象
    private static SingletonLazy instance;
    //3.对外提供获取实例方法
    public static SingletonLazy getInstance() {
        if(instance==null){
            instance = new SingletonLazy();
        }
        return instance;
    }
}
//2.2懒汉式 特点：线程安全同步写法，效率低，
class SingletonLazy2 {
    //1.私有化构造
    private SingletonLazy2(){}
    //2.类内部创建对象
    private static SingletonLazy2 instance;
    //3.对外提供获取实例方法
    public static synchronized SingletonLazy2 getInstance() {
        if(instance==null){
            instance = new SingletonLazy2();
        }
        return instance;
    }
}

//3 双重检测
class SingletonDoubleCheck {
    //1.私有化构造
    private SingletonDoubleCheck() {}

    //2.类内部创建对象
    private static volatile SingletonDoubleCheck instance;

    //3.对外提供获取实例方法
    public static SingletonDoubleCheck getInstance() {
        if (instance == null) {
            synchronized (SingletonDoubleCheck.class) {
                if (instance == null) {
                    instance = new SingletonDoubleCheck();
                }

            }
        }
        return instance;
    }
}

//4.静态内部类
class SingletonStaticClass {

    //1.私有化构造
    private SingletonStaticClass() {}

    //2.内部类
    private static class SingletonInstance {
        private static final SingletonStaticClass INSTANCE = new SingletonStaticClass();
    }

    //3.对外提供获取实例方法
    public static SingletonStaticClass getInstance() {
        return SingletonInstance.INSTANCE;
    }
}

//5.枚举
enum SingleEnum {
    INSTANCE;
    public void method(){

    }
}

public class SingletonTest {

    public static void main(String[] args) {
//        SingletonHungry creation.singleton = SingletonHungry.getInstance();
//        System.out.println(creation.singleton);
//        SingletonHungry singleton2 = SingletonHungry.getInstance();
//        System.out.println(singleton2);
//        System.out.println(creation.singleton==singleton2);

        System.out.println(SingletonDoubleCheck.getInstance());
        System.out.println(SingleEnum.INSTANCE);
    }
}













